home *** CD-ROM | disk | FTP | other *** search
- #ifndef __STD_RW_NUMBRW_CC__
- #define __STD_RW_NUMBRW_CC__
- #pragma option push -b -a4 -Vx- -Ve- -w-inl -w-aus -w-sig
-
- /****************************************************************************
- *
- * rw/numbrw.cc - Internal classes for numeric formatting and parsing.
- *
- * $Id: numbrw.cc,v 1.23 1996/10/22 05:12:47 delaney Exp $
- *
- ***************************************************************************
- *
- * (c) Copyright 1994, 1995 Rogue Wave Software, Inc.
- * ALL RIGHTS RESERVED *
- * The software and information contained herein are proprietary to, and
- * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
- * intends to preserve as trade secrets such software and information.
- * This software is furnished pursuant to a written license agreement and
- * may be used, copied, transmitted, and stored only in accordance with
- * the terms of such license and with the inclusion of the above copyright
- * notice. This software and information or any other copies thereof may
- * not be provided or otherwise made available to any other person.
- *
- * Notwithstanding any other lease or license that may pertain to, or
- * accompany the delivery of, this computer software and information, the
- * rights of the Government regarding its use, reproduction and disclosure
- * are as set forth in Section 52.227-19 of the FARS Computer
- * Software-Restricted Rights clause.
- *
- * Use, duplication, or disclosure by the Government is subject to
- * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
- * Technical Data and Computer Software clause at DFARS 252.227-7013.
- * Contractor/Manufacturer is Rogue Wave Software, Inc.,
- * P.O. Box 2328, Corvallis, Oregon 97339.
- *
- * This computer software and information is distributed with "restricted
- * rights." Use, duplication or disclosure is subject to restrictions as
- * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
- * Computer Software-Restricted Rights (April 1985)." If the Clause at
- * 18-52.227-74 "Rights in Data General" is specified in the contract,
- * then the "Alternate III" clause applies.
- *
- ***************************************************************************/
-
-
- #ifndef _RWSTD_NO_NAMESPACE
- namespace __rwstd {
- #endif
-
- // ------------------------------------------------
- // Template timepunct_data<charT> member templates.
- // ------------------------------------------------
-
- template <class charT>
- timepunct_data<charT>::timepunct_data
- (const timepunct_init<charT> &init)
- {
- int i;
- for (i=0; i<7; i++) {
- dn_[i][0]=init.dn_[i][0];
- dn_[i][1]=init.dn_[i][1];
- }
- for (i=0; i<12; i++) {
- mn_[i][0]=init.mn_[i][0];
- mn_[i][1]=init.mn_[i][1];
- }
- ampm_[0]=init.ampm_[0];
- ampm_[1]=init.ampm_[1];
- bad_=init.bad_;
- for (i=0; i<100; i++)
- ord_[i]=init.ord_[i];
- for (i=0; i<sizeof pat_/sizeof pat_[0]; i++)
- pat_[i]=init.pat_[i];
- }
-
- template <class charT>
- void timepunct_data<charT>::rw_init (void) {
- int i;
- for (i=0; i<7; i++) {
- dn_defs_[i][0].s=dn_[i][0].c_str();
- dn_defs_[i][0].v=i;
- dn_defs_[i][1].s=dn_[i][1].c_str();
- dn_defs_[i][1].v=i;
- }
-
- for (i=0; i<12; i++) {
- mn_defs_[i][0].s=mn_[i][0].c_str();
- mn_defs_[i][0].v=i;
- mn_defs_[i][1].s=mn_[i][1].c_str();
- mn_defs_[i][1].v=i;
- }
-
- dn_map_.num_defs_=7*2;
- dn_map_.defs_=&(dn_defs_[0][0]);
- mn_map_.num_defs_=12*2;
- mn_map_.defs_=&(mn_defs_[0][0]);
- }
-
-
- // -----------------------------------------------
- // Facet rwstd::timepunct<charT> member templates.
- // -----------------------------------------------
-
- #ifndef _RWSTD_NO_NAMESPACE
- } namespace __rwstd { // Leave std, enter __rwstd
- #endif
-
- template <class charT>
- locale::id timepunct<charT>::id;
-
- template <class charT>
- void timepunct<charT>::rw_init () {
- int n;
- for (n=0; n<7; n++) {
- this->dn_[n][false]=do_dayname(n,false);
- this->dn_[n][true]=do_dayname(n,true);
- }
- for (n=0; n<12; n++) {
- this->mn_[n][false]=do_monthname(n,false);
- this->mn_[n][true]=do_monthname(n,true);
- }
- for (n=0; n<100; n++)
- this->ord_[n]=do_ordinal(n);
-
- timepunct_impl<charT>::rw_init();
- }
-
- template <class charT>
- _TYPENAME timepunct<charT>::string_type
- timepunct<charT>::do_dayname (int day, bool abbr) const {
- return this->dn_[day][abbr];
- }
-
- template <class charT>
- _TYPENAME timepunct<charT>::string_type
- timepunct<charT>::do_monthname (int mon, bool abbr) const {
- return this->mn_[mon][abbr];
- }
-
- template <class charT>
- _TYPENAME timepunct<charT>::string_type
- timepunct<charT>::do_ordinal (int number) const {
- return (number<0 || number>99) ? this->bad_ : this->ord_[number];
- }
-
-
-
- // -----------------------------------------------
- // Template digit_handler_base_1 member templates.
- // -----------------------------------------------
-
- template <class charT>
- digit_handler_base_1<charT>::
- digit_handler_base_1 (const locale &loc):
- #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
- ctyp(use_facet<ctype<charT> >(loc)),
- dmap(digit_map<charT>::get_digit_map(ctyp)),
- punct(use_facet<numpunct<charT> >(loc))
- #else
- ctyp(use_facet(loc,(ctype<charT>*)0)),
- dmap(digit_map<charT>::get_digit_map(ctyp)),
- punct(use_facet(loc,(numpunct<charT>*)0))
- #endif
- { }
-
- template <class charT>
- digit_handler_base_1<charT>::
- digit_handler_base_1
- (const locale &loc, const punct_data<charT> &pun):
- #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
- ctyp(use_facet<ctype<charT> >(loc)),
- dmap(digit_map<charT>::get_digit_map(ctyp)),
- #else
- ctyp(use_facet(loc,(ctype<charT>*)0)),
- dmap(digit_map<charT>::get_digit_map(ctyp)),
- #endif
- punct(pun)
- { }
-
- // ----------------------------------------------
- // Template digit_reader_base_1 member templates.
- // ----------------------------------------------
-
- template <class charT>
- digit_reader_base_1<charT>::
- digit_reader_base_1 (const locale &loc):
- digit_handler_base_1<charT>(loc)
- { }
-
- template <class charT>
- digit_reader_base_1<charT>::
- digit_reader_base_1 (const locale &loc,
- const punct_data<charT> &mp):
- digit_handler_base_1<charT>(loc,mp)
- { }
-
- // ---------------------------------------
- // Template digit_reader member templates.
- // ---------------------------------------
-
- template <class charT,class InputIterator>
- digit_reader<charT,InputIterator>::
- digit_reader(InputIterator& i,InputIterator& e,ios_base &b):
- digit_reader_base_1<charT>(b.getloc()),
- io(b), in(i), end(e)
- { }
-
- template <class charT,class InputIterator>
- digit_reader<charT,InputIterator>::
- digit_reader(InputIterator& i,InputIterator& e,ios_base &b,
- const punct_data<charT> &mp):
- digit_reader_base_1<charT>(b.getloc(),mp),
- io(b), in(i), end(e)
- { }
-
- template <class charT,class InputIterator>
- char* digit_reader<charT,InputIterator>::
- get_digit_string (char *dpos)
- {
- char *eod=dpos;
- int i;
-
- while (!at_end() && (i=this->dmap.eval(*in))>=0 && i<this->radix) {
- if (eod==this->digits+sizeof this->digits)
- this->error|=this->too_many_digits;
- else
- *eod++=(char) i;
- ++in;
- }
-
- return eod;
- }
-
- template <class charT,class InputIterator>
- char* digit_reader<charT,InputIterator>::
- get_int_digits (void)
- {
- charT c;
- char *eod=this->digits;
- const charT* ctype_punct=this->dmap.get_punct();
-
- if (!at_end() && this->is_signed)
- // If a sign is present, set negative if it's a minus sign.
- do {
- if ((c=*in)==ctype_punct[this->minus])
- this->negative=true;
- else if (c!=ctype_punct[this->plus])
- break;
- // Eat white space after the sign. Standard seems to mandate this
- // regardless of whether ios_base::skipws is set.
- do
- ++in;
- while (!at_end() && this->ctyp.is(ctype_base::space,*in));
- this->advanced=true;
- } while (0);
-
- if (!this->radix) {
- switch (io.flags() & ios_base::basefield) {
- case ios_base::dec:
- this->radix=10;
- break;
- case ios_base::hex:
- this->radix=16;
- break;
- case ios_base::oct:
- this->radix=8;
- break;
- default:
- // No radix was forced by the ios_base flags, so poke around for a radix
- // specifier on the front of the input value.
- this->radix=10;
- if (!at_end() && *in==ctype_punct[this->zero]) {
- this->radix=8;
- ++in;
- *eod++=0;
- this->advanced=true;
- if (!at_end() &&
- ((c=*in)==ctype_punct[this->x] || c==ctype_punct[this->X]))
- {
- this->radix=16;
- ++in;
- eod--; // Leading 0 was not a digit after all.
- }
- }
- }
- }
-
- grouping=this->get_grouping();
- if (!*grouping)
- eod=get_digit_string(eod);
- else {
- gpos=groups;
- thousands_sep=get_thousands_sep();
- eod=get_digit_groups(eod);
- if (!this->error && --gpos>groups) {
- // Digit grouping is optional, but if present it must be right.
- const char *gdef=grouping;
- do {
- if (*gdef!=*gpos && *gdef!=CHAR_MAX)
- break;
- else
- if (gdef[1])
- gdef++;
- } while (--gpos>groups);
-
- if (gpos>groups || *gpos>*gdef)
- this->error|=this->bad_grouping;
- }
- }
-
- if (eod>this->digits)
- this->advanced=true;
- return eod;
- }
-
- template <class charT,class InputIterator>
- char* digit_reader<charT,InputIterator>::
- get_float_digits (void)
- {
- charT c;
- this->radix=10;
- char *eod=get_int_digits();
-
- const charT *ctyp_punct=this->dmap.get_punct();
-
- this->frac_beg=eod;
- if (!this->error && !at_end() && *in==get_decimal_point()) {
- in++;
- eod=get_digit_string(eod);
- }
-
- if (eod==this->digits)
- this->error|=this->no_digits;
-
- this->exp_beg=eod;
- this->exp_negative=false;
- if (!this->error && !at_end() &&
- ((c=*in)==ctyp_punct[this->e] || c==ctyp_punct[this->E]))
- {
- in++;
- if (at_end())
- this->error|=this->bad_exponent;
- else {
- if ((c=*in)==ctyp_punct[this->plus])
- in++;
- else if (c==ctyp_punct[this->minus]) {
- this->exp_negative=true;
- in++;
- }
-
- int save_radix=this->radix;
- this->radix=10;
- eod=get_digit_string(eod);
- this->radix=save_radix;
- if (eod==this->exp_beg)
- this->error|=this->bad_exponent;
- }
- }
-
- return eod;
- }
-
- template <class charT,class InputIterator>
- char *digit_reader<charT,InputIterator>::
- get_pointer_digits (void)
- {
- this->radix=16;
- char *eod=get_int_digits();
- return eod;
- }
-
- template <class charT,class InputIterator>
- char* digit_reader<charT,InputIterator>::
- get_digit_groups (char *dpos)
- {
- char *eod=get_digit_string(dpos);
-
- if (gpos==groups+sizeof groups)
- this->error|=this->too_many_groups;
- else {
- int i=eod-dpos;
- if (i >= CHAR_MAX)
- this->error|=this->group_too_long;
- else {
- *gpos++=i;
- if (i!=0 && !at_end() && *in==thousands_sep) {
- ++in;
- eod=get_digit_groups(eod);
- }
- }
- }
-
- return eod;
- }
-
- template <class charT,class InputIterator>
- int digit_reader<charT,InputIterator>::
- get_keyword (const keyword_map<charT> &mapit)
- {
- const keyword_def<charT> *canp=mapit.defs_;
- const keyword_def<charT> *endp=mapit.defs_+mapit.num_defs_;
- keyword_def<charT> cans[40],*ansp=cans;
-
- charT c;
- const charT *p;
- int result;
-
- while (1) {
- if (at_end()) {
- for ( ; canp<endp; canp++)
- if (!*canp->s)
- return canp->v;
- return -1;
- }
- c=*in;
- result=-1;
- for ( ; canp<endp; canp++) {
- p=canp->s;
- if (c==*p) {
- ansp->s=++p;
- ansp->v=canp->v;
- ansp++;
- } else if (*p==0)
- result=ansp->v; // abbreviation
- }
-
- if (ansp==cans)
- return result;
- in++;
- if (ansp==cans+1) {
- for (p=cans[0].s; *p; p++) {
- if (at_end() || *in!=*p)
- return -1;
- in++;
- }
- return cans[0].v;
- }
-
- endp=ansp;
- ansp=cans;
- canp=cans;
- }
- }
-
- // ----------------------------------------------
- // Template digit_writer_base_1 member templates.
- // ----------------------------------------------
-
- template <class charT>
- digit_writer_base_1<charT>::
- digit_writer_base_1(ios_base &b,const locale &loc)
- : digit_writer_base(b), digit_handler_base_1<charT>(loc)
- { }
-
- template <class charT>
- digit_writer_base_1<charT>::
- digit_writer_base_1(ios_base &b,const punct_data<charT> &mp)
- : digit_writer_base(b),digit_handler_base_1<charT>(b.getloc(),mp)
- {
- flags&=~(ios_base::floatfield|ios_base::showpos);
- flags|=ios_base::fixed;
- radix=10;
- precision=0;
- }
-
- // ---------------------------------------
- // Template digit_writer member templates.
- // ---------------------------------------
-
- template <class charT,class OutputIterator>
- digit_writer<charT,OutputIterator>::
- digit_writer (OutputIterator &o, ios_base &b)
- : digit_writer_base_1<charT>(b,b.getloc()), out(o)
- { }
-
- template <class charT,class OutputIterator>
- digit_writer<charT,OutputIterator>::
- digit_writer (OutputIterator &o, ios_base &b,
- const punct_data<charT> &mp)
- : digit_writer_base_1<charT>(b,mp), out(o)
- { }
-
- template <class charT, class OutputIterator>
- void digit_writer<charT,OutputIterator>::put_digits (charT fill)
- {
- char *p=this->start;
- bool has_sign=false,has_point=false;
- if (p<this->end && (*p==' ' || *p=='-' || *p=='+'))
- has_sign=true;
-
- // Locate the end of the integral digits.
- char *dec;
- if (!this->fractional)
- dec=this->end;
- else {
- dec=this->start;
- if (has_sign) dec++;
- for ( ; dec<this->end; dec++)
- if (*dec<'0' || *dec>'9') {
- if (*dec!='e' && *dec!='E')
- has_point=true;
- break;
- }
- }
-
- // Calculate the number and pattern of separators needed if any.
- charT separator;
- int unGrouped=dec-this->start;
- if (has_sign)
- unGrouped--;
- if (this->radix==10 && this->separable) {
- unGrouped=calc_groups(unGrouped,this->get_grouping());
- if (this->num_groups)
- separator=get_thousands_sep();
- }
-
- // Compute the number of fill charT-s needed, and where they should be put.
- int leftFill=0,internalFill=0,rightFill=0;
- if (this->width>0) {
- int w=this->width - (this->end - this->start) - this->num_groups;
- this->width=0;
- if (w>0) {
- switch (this->adjust) {
- case digit_writer_base::left:
- rightFill=w;
- break;
- case digit_writer_base::internal:
- internalFill=w;
- break;
- default:
- leftFill=w;
- }
- }
- }
-
- // Widen the sign + digits + exponent string.
- //charT wide_digits[sizeof digit_writer_base::buffer];
- charT wide_digits[400];
- this->ctyp.widen(this->start,this->end,wide_digits);
-
- // Write the widened string with fill and decorations to output.
- charT *digit_pos=wide_digits;
- while (leftFill--)
- *out++=fill;
- if (has_sign)
- *out++=*digit_pos++; // the widened sign
- while (internalFill--)
- *out++=fill;
- while (unGrouped--)
- *out++=*digit_pos++;
- while (this->num_groups--) {
- *out++=separator;
- while (this->group[0]--)
- *out++=*digit_pos++;
- this->group++;
- }
-
- if (has_point) {
- *out++=get_decimal_point();
- digit_pos++;
- }
-
- unGrouped=this->end-dec;
- if (has_point)
- unGrouped--;
- while (unGrouped-->0)
- *out++=*digit_pos++;
-
- while (rightFill--)
- *out++=fill;
- }
-
- template <class charT, class OutputIterator>
- void digit_writer<charT,OutputIterator>::
- put_keyword (const string_type &k, charT fill)
- {
- int leftFill=0,rightFill=0;
- int n=this->width-k.length();
- if (n>0) {
- switch (this->adjust) {
- case digit_writer_base::left:
- rightFill=n;
- break;
- case digit_writer_base::internal:
- default:
- leftFill=n;
- }
- if (leftFill)
- do *out++=fill;
- while (--leftFill);
- }
-
- const charT *p=k.c_str(),*end=p+k.length();
- while (p<end)
- *out++=*p++;
-
- if (rightFill)
- do *out++=fill;
- while (--rightFill);
- }
-
- #ifndef _RWSTD_NO_NAMESPACE
- } // namespace __rwstd
- #endif
-
- #pragma option pop
- #endif // __STD_RW_NUMBRW_CC__
-